package org.umlviewer.model.sequence_diagram;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import org.umlviewer.model.Constants;
import org.umlviewer.model.Relationship;
import org.umlviewer.model.diagram_class.Method;
import org.umlviewer.paint.ArrowHead;
import org.umlviewer.paint.ArrowHeadTriangle;
import org.umlviewer.paint.PaintUtils;

/**
 *
 * @author Rafa
 */
//mensaje entre instancias
public class Message extends Relationship{

    private Point srcPoint;
    private Point dstPoint;
    private Method method;
    private final int wr = 8, hr = 18;
    //destination y source serian LifeLine
    private int seqno;
    private static int counter=1;
    
    public Message(){
        super();
        srcPoint = new Point(0, 0);
        dstPoint = new Point(0, 0);
        method = new Method();
        method.setName("metodo()");
        setType(Relationship.MESSAGE);
        seqno = counter++;
    }

    public Point getDstPoint() {
        return dstPoint;
    }

    public void setDstPoint(Point dstPoint) {
        this.dstPoint = dstPoint;
    }

    public Point getSrcPoint() {
        return srcPoint;
    }

    public void setSrcPoint(Point srcPoint) {
        this.srcPoint = srcPoint;
    }
    
    public void setMethod(Method m){
        this.method = m;
    }
            
    //sobrescribe el metodo del padre
    @Override
    public void paint(Graphics g){
        int midX, midY;                
        ArrowHead head=null;
        //TODO: cuando es una recursion
        Point2D src = getSource().getRelPoint(getDestination().getMidPoint());
        Point2D dst = getDestination().getRelPoint(getSource().getMidPoint());        
        srcPoint.y = (int)src.getY()+30*seqno;
        dstPoint.y = (int)dst.getY()+30*seqno;
        //hacer que crezca el lifeline
        if( (getSource().getPosY()+getSource().getHeight()) < srcPoint.y){
            getSource().resize(new Rectangle(getSource().getPosX(), getSource().getPosY(), getSource().getWidth(), srcPoint.y +30));
            getDestination().resize(new Rectangle(getDestination().getPosX(), getDestination().getPosY(), getDestination().getWidth(), srcPoint.y +30));
        }
        //el rectangulo del comiezo
        g.drawRect((int)src.getX()-wr/2, srcPoint.y, wr, hr);
        g.setColor(Color.white);
        g.fillRect((int)src.getX()-wr/2+1, srcPoint.y+1, wr-1, hr-1);
        g.setColor(Color.black);
        //el cuerpo del mensaje
        g.drawLine((int)src.getX(), srcPoint.y, (int)dst.getX(), dstPoint.y);
        head = new ArrowHeadTriangle();
        head.setArrowWidth(4);
        srcPoint.x = (int)src.getX();
        dstPoint.x = (int)dst.getX();
        head.paint(g, srcPoint, dstPoint, Color.black, Color.black);
        //el rectangulo del final
        g.drawRect((int)dst.getX()-wr/2, dstPoint.y, wr, hr);        
        g.setColor(Color.white);
        g.fillRect((int)dst.getX()-wr/2+1, dstPoint.y+1, wr-1, hr-1);        
        g.setColor(Color.black);
        //nombre del mensaje o metodo
        midX = ((int)dst.getX() - (int)src.getX()) /2;
        midY = (dstPoint.y - srcPoint.y) /2;
        g.drawString(method.getName(), (int)src.getX() + midX, srcPoint.y + midY-5);
        
         //si la linea esta seleccionada
        if(isSelected())
        {
            g.setColor(Constants.SELECTIONCOLOR);
            g.fillRect((int)src.getX(), srcPoint.y, 5, 5);
            g.fillRect((int)dst.getX(), dstPoint.y, 5, 5);
            g.setColor(Constants.DEFAULTCOLOR);
        }
    }
    
    //sobreescribe contains por la forma en que se pinta el mensaje
     public boolean contains(int x, int y){
        double dstX, dstY;
        double srcX, srcY;       
        
        if(getSource()!=null && getDestination()!=null){
            Point2D q = getSource().getRelPoint(getDestination().getMidPoint());
            Point2D p = getDestination().getRelPoint(getSource().getMidPoint());
            srcX = q.getX();
            srcY = srcPoint.y; 
            
            dstX = p.getX();
            dstY = dstPoint.y;
            
            return (PaintUtils.ptSegDist(srcX, srcY, dstX, dstY, x, y)<=4.0);
        }
        return false;
    }
    
}
